/**
 * 
 */
package org.chungyan5.lib.android.gcal;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.chungyan5.lib.android.gcal.CalendarContract.Calendars;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.os.Build;

/**
 * @author yan
 *
 */
public abstract class GoogleCalendarAPI {

	private static GoogleCalendarAPI api;
	
	protected static Context context;
	protected static ContentResolver cr;
	
	public Cursor calendarsCursor;
	
	protected String testStr = "Test3 ";//
	public abstract String getTestStr();//
	
	public static GoogleCalendarAPI getAPI(Context c) {
		
		context = c;
		cr = context.getContentResolver();
		
		// inject diff. implementation for diff. version of Android ===========
		String apiClass;
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
			apiClass = "org.chungyan5.lib.android.gcal.SdkVer14Plus";
		} else {
			apiClass = "org.chungyan5.lib.android.gcal.SdkVer8Plus";
		}
		
		try {
			Class<? extends GoogleCalendarAPI> realClass = 
					Class.forName(apiClass).asSubclass(GoogleCalendarAPI.class);
			api = realClass.newInstance();
		} catch (Exception e) {
			throw new IllegalStateException(e);
		}
		
		return api;
	}
	
	public abstract boolean read();
	public abstract boolean insert();
	public abstract boolean update();
	public abstract boolean remove();
	
	public static final int CALENDAR_ID_CURSOR_POS = 0;
	public static final int CALENDAR_DISPLAY_NAME_CURSOR_POS = 1;
	public GCal getCalendar(String calendarID, String display_name) {
		
		String selection, selectionArg;
		if (calendarID != null) {
			selection = Calendars._ID;
			selectionArg = calendarID;
		} else {
			selection = Calendars.CALENDAR_DISPLAY_NAME;
			selectionArg = display_name;
		}
		GCalList gCalList = new GCalList(cr.query(
				Calendars.CONTENT_URI, 
				(new String[] { Calendars._ID, Calendars.CALENDAR_DISPLAY_NAME}), 
				selection + " = ?",
				new String[] { selectionArg }, 
				null));
		if (gCalList.moveToNext()) 
			return gCalList.getRecord();
		else 
			return null;
	}
	
	/**
	 * @return list of calenders in GCal object
	 */
	public GCalList listAllCalendars() {

		return new GCalList(cr.query(
				Calendars.CONTENT_URI, 
				(new String[] { Calendars._ID, Calendars.CALENDAR_DISPLAY_NAME}), null, null, null));
	}
	
	public static final int INSTANCES_ID_CURSOR_POS = 0;
	public static final int INSTANCES_EVENT_TITLE_CURSOR_POS = 1;
	public static final int INSTANCES_BEGIN_DATE_CURSOR_POS = 2;
	public static final int INSTANCES_END_DATE_CURSOR_POS = 3;
	public static final int INSTANCES_DURATION_CURSOR_POS = 4;
	public static final int INSTANCES_ALL_DAY_CURSOR_POS = 5;
	public static final int INSTANCES_CALENDAR_ID_CURSOR_POS = 6;
	public abstract GCalEventList listAllEvents(Calendar beginningDate, Calendar endDate, GCal gcal);
	
	/**
	 * General Budget and Time sheet Report
	 *  
	 * @param arrGCal Google Calendars List
	 * @param startDate starting day of this report in Calendar format
	 * @param lenDay length in day
	 * @param lenMonth length in month
	 * @param lenYear length in year
	 * @return
	 */
	public HashMap<String,Number> generateTimeReport(List<GCal> arrGCal, Calendar startDate, int lenDay, int lenMonth, int lenYear) {
		Calendar endDate = (Calendar) startDate.clone();
		endDate.add(Calendar.DAY_OF_MONTH, lenDay);
		endDate.add(Calendar.MONTH, lenMonth);
		endDate.add(Calendar.YEAR, lenYear);
		return generateTimeReport(arrGCal, startDate, endDate);
	}
		
	/**
	 * @param arrGCal
	 * @param startDate
	 * @param endDate end day of this report
	 * @return
	 */
	public HashMap<String,Number> generateTimeReport(List<GCal> arrGCal, Calendar startDate, Calendar endDate) {
		
		HashMap<String,Number> projectsArray = new HashMap<String,Number>();
		
		endDate.add(Calendar.SECOND, -1);	// not include the last second event(s)
		
		Iterator<GCal> it = arrGCal.iterator();
		while (it.hasNext()) {

			/*AccountManager manager = AccountManager.get(context);
				Account[] accounts = manager.getAccountsByType("com.google");
//				Account[] accounts = manager.getAccounts();
				
				String accountName = "";
			    String accountType = "";

			    int b = 0;
			    for (Account account : accounts) {
			        accountName += account.name;
			        accountType += account.type;
			        b++;
			    }*/
			
			GCalEventList gCalEventList = listAllEvents(startDate, endDate, it.next());
			while (gCalEventList.moveToNext()) {
				
				GCalEvent gCalEvent = gCalEventList.getRecord();
				
				if (!gCalEvent.getAllDay()) {			// TODO default as Filter whole day events
					
					String eventTitle = gCalEvent.getTitle();
					String[] eventTitleArr = eventTitle.split(":");
					
					float hr = Long.valueOf((gCalEvent.getEndTime() - gCalEvent.getStartTime()) / (1000L * 60L)).floatValue() / 60f;
					if (projectsArray.containsKey( eventTitleArr[0] )) {
						hr += projectsArray.get(eventTitleArr[0]).floatValue();
					}
//	projectsArray.put(eventTitle, hr);
					projectsArray.put(eventTitleArr[0], hr);
				}
				
			}
		}
	
		return projectsArray; 
	}

}
